package com.ptu.ws;

import com.alibaba.fastjson.JSON;
import com.ptu.dto.UserDTO;
import com.ptu.entity.ChatMessage;
import com.ptu.util.JwtUtil;
import com.ptu.ws.service.ChatMessageService;
import io.jsonwebtoken.Claims;
import jakarta.websocket.*;
import jakarta.websocket.server.ServerEndpoint;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.io.IOException;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

@ServerEndpoint("/customer")
@Component
public class CustomerEndpoint {

    private static JwtUtil jwtUtil;
    private static ChatMessageService chatMessageService;

    @Autowired
    public static void setJwtUtil(JwtUtil util) {
        CustomerEndpoint.jwtUtil = util;
    }

    @Autowired
    public static void setChatMessageService(ChatMessageService service) {
        CustomerEndpoint.chatMessageService = service;
    }

    // 在线用户会话映射 (用户名 -> Session)
    private static final Map<String, Session> userMap = new ConcurrentHashMap<>();
    // 存储管理员会话
    private static Session adminSession = null;
    // 用户消息历史 (用户名 -> 消息列表)
    private static final Map<String, List<Message>> userMessages = new ConcurrentHashMap<>();
    // 会话反向映射 (Session -> 用户名)
    private static final Map<Session, String> sessionUserMap = new ConcurrentHashMap<>();

    // 连接建立成功调用的方法
    @OnOpen
    public void onOpen(Session session) {
        try {
            System.out.println("尝试连接");

            // 从请求参数中获取token
            String token = session.getRequestParameterMap().get("token").get(0);

            // 解析token获取用户名
            Claims claims = jwtUtil.parseToken(token);
            String username = claims.get("username", String.class);
            System.out.println("用户名: " + username);

            // 保存会话与用户的映射关系
            sessionUserMap.put(session, username);

            // 判断是否是管理员
            if ("admin".equals(username)) {
                adminSession = session; // 保存管理员会话
                // 发送系统消息
                sendSystemMessage(session, "管理员已上线");
                // 发送在线用户列表
                sendOnlineUsers();
            } else {
                // 普通用户
                userMap.put(username, session);
                // 初始化用户消息列表
                userMessages.putIfAbsent(username, new ArrayList<>());
                // 通知管理员新用户上线
                if (adminSession != null) {
                    sendSystemMessage(adminSession, username + " 已上线");
                    sendOnlineUsers();
                }
            }

            // 加载历史消息
            String otherUser = "admin".equals(username) ? null : "admin"; //  获取与当前用户对话的用户
            if (otherUser != null) {
                List<ChatMessage> history = chatMessageService.getMessagesBetweenUsers(username, otherUser, 50);
                if (!history.isEmpty()) {
                    for (ChatMessage msg : history) {
                        Message wsMessage = new Message();
                        wsMessage.setType(MessageType.MESSAGE);
                        wsMessage.setContent(msg.getContent());
                        wsMessage.setSender(msg.getSender());
                        wsMessage.setToName(msg.getReceiver());
                        session.getBasicRemote().sendText(JSON.toJSONString(wsMessage));
                    }
                }
            }

            System.out.println(username + " 连接成功");
        } catch (Exception e) {
            System.err.println("连接建立失败: " + e.getMessage());
        }
    }

    // 接收消息调用的方法
    @OnMessage
    public void onMessage(String messageStr, Session session) {
        try {
            // 解析消息
            Message message = JSON.parseObject(messageStr, Message.class);
            System.out.println("收到消息: " + message);
            String username = sessionUserMap.get(session);
            if (username == null) {
                throw new RuntimeException("未找到用户信息");
            }
            switch (message.getType()) {
                case MESSAGE:
                    handleMessage(message, username);
                    break;
                case GET_ONLINE_USERS:
                    if ("admin".equals(username)) {
                        sendOnlineUsers();
                    }
                    break;
                default:
                    System.out.println("未知消息类型: " + message.getType());
            }
        } catch (Exception e) {
            System.err.println("消息处理失败: " + e.getMessage());
            try {
                sendSystemMessage(session, "消息处理失败");
            } catch (IOException ex) {
                throw new RuntimeException(ex);
            }
        }
    }

    // 连接关闭调用的方法
    @OnClose
    public void onClose(Session session) {
        try {
            String username = sessionUserMap.remove(session);
            if (username == null) {
                return;
            }

            if ("admin".equals(username)) {
                adminSession = null;
                // 通知所有用户管理员下线
                broadcastSystemMessage("管理员已下线");
            } else {
                userMap.remove(username);
                // 通知管理员用户下线
                if (adminSession != null) {
                    sendSystemMessage(adminSession, username + " 已下线");
                    sendOnlineUsers();
                }
            }

            System.out.println(username + " 连接关闭");
        } catch (Exception e) {
            System.err.println("连接关闭处理失败: " + e.getMessage());
        }
    }

    @OnError
    public void onError(Session session, Throwable error) {
        System.err.println("WebSocket错误: " + error.getMessage());
        try {
            sendSystemMessage(session, "连接发生错误");
        } catch (IOException e) {
            System.err.println("发送错误消息失败: " + e.getMessage());
        }
    }

    // 处理普通消息
    private void handleMessage(Message message, String sender) throws IOException {
        message.setSender(sender); // 设置发送者

        // 创建 ChatMessage 对象并保存到数据库
        ChatMessage chatMessage = new ChatMessage();
        chatMessage.setSender(sender);
        chatMessage.setReceiver(message.getToName());
        chatMessage.setContent(message.getContent());
        chatMessage.setType("text");
        chatMessage.setStatus(0);
        chatMessage.setCreateTime(LocalDateTime.now());
        
        // 生成会话ID
        String sessionId = sender.compareTo(message.getToName()) < 0 
            ? sender + "_" + message.getToName() 
            : message.getToName() + "_" + sender;
        chatMessage.setSessionId(sessionId);
        
        // 保存消息到数据库
        chatMessageService.saveMessage(chatMessage);

        // 存储普通用户消息
        if (!"admin".equals(sender)) {
            userMessages.get(sender).add(message);
        }

        // 发送消息
        if ("admin".equals(message.getToName())) {
            // 用户发送给管理员
            if (adminSession != null) {
                adminSession.getBasicRemote().sendText(JSON.toJSONString(message));
            }
        } else {
            // 管理员发送给用户
            Session userSession = userMap.get(message.getToName());
            if (userSession != null) {
                userSession.getBasicRemote().sendText(JSON.toJSONString(message));
            }
        }
    }

    // 发送系统消息
    private void sendSystemMessage(Session session, String content) throws IOException {
        Message systemMessage = new Message(MessageType.SYSTEM, null, content, "系统");
        session.getBasicRemote().sendText(JSON.toJSONString(systemMessage));
    }

    // 广播系统消息
    private void broadcastSystemMessage(String content) throws IOException {
        Message systemMessage = new Message(MessageType.SYSTEM, null, content, "系统");
        String messageStr = JSON.toJSONString(systemMessage);

        // 发送给所有用户
        for (Session session : userMap.values()) {
            session.getBasicRemote().sendText(messageStr);
        }
    }

    // 发送在线用户列表
    private void sendOnlineUsers() throws IOException {
        if (adminSession != null) {
            Message message = new Message();
            message.setType(MessageType.ONLINE_USERS);
            message.setContent(JSON.toJSONString(new ArrayList<>(userMap.keySet())));
            adminSession.getBasicRemote().sendText(JSON.toJSONString(message));
        }
    }

    // 获取用户历史消息
    public List<Message> getUserMessages(String username) {
        return userMessages.getOrDefault(username, new ArrayList<>());
    }
}